package cn.metona.utils;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;

public final class ObjectUtils {

    // 私有构造函数，防止实例化
    private ObjectUtils() {
        throw new UnsupportedOperationException("Utility class, cannot be instantiated");
    }

    // ------------------------- 基本对象操作 -------------------------

    /**
     * 判断对象是否为空
     */
    public static boolean isNull(Object obj) {
        return obj == null;
    }

    /**
     * 判断对象是否不为空
     */
    public static boolean isNotNull(Object obj) {
        return !isNull(obj);
    }

    /**
     * 如果对象为空，则返回默认值
     */
    public static <T> T defaultIfNull(T obj, T defaultValue) {
        return isNull(obj) ? defaultValue : obj;
    }

    /**
     * 如果对象为空，则通过 Supplier 提供默认值
     */
    public static <T> T defaultIfNull(T obj, Supplier<T> defaultValueSupplier) {
        return isNull(obj) ? defaultValueSupplier.get() : obj;
    }

    /**
     * 检查两个对象是否相等
     */
    public static boolean equals(Object o1, Object o2) {
        return Objects.equals(o1, o2);
    }

    /**
     * 获取对象的哈希码
     */
    public static int hashCode(Object obj) {
        return Objects.hashCode(obj);
    }

    /**
     * 获取对象的字符串表示
     */
    public static String toString(Object obj) {
        return Objects.toString(obj);
    }

    /**
     * 获取对象的类名
     */
    public static String getClassName(Object obj) {
        return isNull(obj) ? "null" : obj.getClass().getName();
    }

    // ------------------------- 对象操作扩展 -------------------------

    /**
     * 如果对象不为空，则执行操作
     */
    public static <T> void ifNotNull(T obj, Consumer<T> action) {
        if (isNotNull(obj)) {
            action.accept(obj);
        }
    }

    /**
     * 如果对象为空，则执行操作
     */
    public static void ifNull(Object obj, Runnable action) {
        if (isNull(obj)) {
            action.run();
        }
    }

    /**
     * 检查对象是否满足条件
     */
    public static <T> boolean satisfies(T obj, Predicate<T> predicate) {
        return isNotNull(obj) && predicate.test(obj);
    }

    /**
     * 将对象转换为另一种类型
     */
    public static <T, R> R convert(T obj, Function<T, R> converter) {
        return isNull(obj) ? null : converter.apply(obj);
    }

    /**
     * 克隆对象（浅拷贝）
     */
    @SuppressWarnings("unchecked")
    public static <T extends Cloneable> T clone(T obj) throws CloneNotSupportedException {
        if (isNull(obj)) {
            return null;
        }
        try {
            return (T) obj.getClass().getMethod("clone").invoke(obj);
        } catch (Exception e) {
            throw new CloneNotSupportedException("Object cannot be cloned");
        }
    }

    // ------------------------- 集合操作 -------------------------

    /**
     * 检查集合是否为空
     */
    public static boolean isEmpty(Collection<?> collection) {
        return isNull(collection) || collection.isEmpty();
    }

    /**
     * 检查集合是否不为空
     */
    public static boolean isNotEmpty(Collection<?> collection) {
        return !isEmpty(collection);
    }

    /**
     * 检查数组是否为空
     */
    public static boolean isEmpty(Object[] array) {
        return isNull(array) || array.length == 0;
    }

    /**
     * 检查数组是否不为空
     */
    public static boolean isNotEmpty(Object[] array) {
        return !isEmpty(array);
    }

    /**
     * 检查 Map 是否为空
     */
    public static boolean isEmpty(Map<?, ?> map) {
        return isNull(map) || map.isEmpty();
    }

    /**
     * 检查 Map 是否不为空
     */
    public static boolean isNotEmpty(Map<?, ?> map) {
        return !isEmpty(map);
    }

    /**
     * 将集合转换为字符串
     */
    public static String join(Collection<?> collection, String delimiter) {
        if (isEmpty(collection)) {
            return "";
        }
        return collection.stream()
                .map(Object::toString)
                .collect(Collectors.joining(delimiter));
    }

    // ------------------------- 数组操作 -------------------------

    /**
     * 将数组转换为列表
     */
    public static <T> List<T> toList(T[] array) {
        return isNull(array) ? Collections.emptyList() : Arrays.asList(array);
    }

    /**
     * 将数组转换为集合
     */
    public static <T> Set<T> toSet(T[] array) {
        return isNull(array) ? Collections.emptySet() : new HashSet<>(Arrays.asList(array));
    }

    // ------------------------- 字符串操作 -------------------------

    /**
     * 检查字符串是否为空
     */
    public static boolean isEmpty(String str) {
        return isNull(str) || str.isEmpty();
    }

    /**
     * 检查字符串是否不为空
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 检查字符串是否为空白
     */
    public static boolean isBlank(String str) {
        return isNull(str) || str.trim().isEmpty();
    }

    /**
     * 检查字符串是否不为空白
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    /**
     * 如果字符串为空，则返回默认值
     */
    public static String defaultIfEmpty(String str, String defaultValue) {
        return isEmpty(str) ? defaultValue : str;
    }

    /**
     * 如果字符串为空白，则返回默认值
     */
    public static String defaultIfBlank(String str, String defaultValue) {
        return isBlank(str) ? defaultValue : str;
    }

    // ------------------------- 异常处理 -------------------------

    /**
     * 抛出运行时异常
     */
    public static void throwRuntimeException(String message) {
        throw new RuntimeException(message);
    }

    /**
     * 如果条件为 true，则抛出运行时异常
     */
    public static void throwIf(boolean condition, String message) {
        if (condition) {
            throw new RuntimeException(message);
        }
    }

    /**
     * 如果对象为空，则抛出运行时异常
     */
    public static void throwIfNull(Object obj, String message) {
        if (isNull(obj)) {
            throw new RuntimeException(message);
        }
    }

    /**
     * 如果对象不为空，则抛出运行时异常
     */
    public static void throwIfNotNull(Object obj, String message) {
        if (isNotNull(obj)) {
            throw new RuntimeException(message);
        }
    }
}